#include "qcolorgroupdialog.h"
#include "ui_qcolorgroupdialog.h"

#include "../../shared/qcommonstruct.h"
#include "../../qwt/qwt_thermo.h"

#include <QMouseEvent>
#include <QPainter>
#include <QColorDialog>

QColorPositionBar::QColorPositionBar(QWidget *parent):
    QWidget(parent),
    m_current_index(-1)
{
    setFixedHeight(15);
    setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Fixed);
    setFocusPolicy(Qt::StrongFocus);
}

QColorPositionBar::~QColorPositionBar()
{
    qDeleteAll(m_positions);
    m_positions.clear();
}

void QColorPositionBar::set_current(int index)
{
    if(index<0)
    {
        index=0;
    }
    else if(index>=m_positions.size())
    {
        index=m_positions.size()-1;
    }
    if(m_current_index!=index)
    {
        m_current_index=index;
        update();
        emit current_changed();
    }
}

QList<tagColorPosition*> QColorPositionBar::get_positions()
{
    return m_positions;
}

tagColorPosition* QColorPositionBar::get_position(int index)
{
    return m_positions.at(index);
}

int QColorPositionBar::get_current()
{
    return m_current_index;
}

void QColorPositionBar::mousePressEvent(QMouseEvent *e)
{
    if(e->button()==Qt::LeftButton)
    {
        m_is_clicked=true;
        m_press_position=e->pos();
        int x;
        QRect re;
        int wid=this->width()-21;
        tagColorPosition *pos;
        for(int i=m_positions.size()-1;i>=0;i--)
        {
            pos=m_positions.at(i);
            x=10+wid*pos->m_position/100;
            re.setRect(x-5,0,10,15);
            if(re.contains(e->pos()))
            {
                set_current(m_positions.indexOf(pos));
                m_press_pos=pos->m_position;
                return;
            }
        }
        m_is_clicked=false;
    }
}

void QColorPositionBar::mouseMoveEvent(QMouseEvent *e)
{
    if(m_is_clicked)
    {
        if(m_current_index>1)
        {
            int p=m_press_pos+(e->x()-m_press_position.x())*100/(width()-21);
            if(p<0)
            {
                p=0;
            }
            else if(p>100)
            {
                p=100;
            }
            set_position(m_current_index,p);
        }
    }
}

void QColorPositionBar::set_position(int index, int pos)
{
    tagColorPosition *p=m_positions.at(index);
    if(p->m_position!=pos)
    {
        p->m_position=pos;
        emit refresh();
    }
}

void QColorPositionBar::add_position(int pos, const QColor &color)
{
    tagColorPosition *p=new tagColorPosition;
    p->m_color=color;
    p->m_position=pos;
    m_positions.append(p);
}

void QColorPositionBar::remove_position(int pos)
{
    if(pos<2)
    {
        return ;
    }

    delete m_positions.takeAt(pos);
    int x=m_current_index;
    m_current_index=-1;

    set_current(x);
    emit refresh();
}

void QColorPositionBar::mouseReleaseEvent(QMouseEvent *e)
{
    m_is_clicked=false;
}

void QColorPositionBar::paintEvent(QPaintEvent *)
{
    QPainter p(this);

    p.fillRect(10,0,this->width()-21,height(),QBrush(QColor(192,192,192)));
    int x;
    QRect re=rect();
    tagColorPosition *pos;
    for(int i=0;i<m_positions.size();i++)
    {
        if(i==m_current_index)
        {
            continue;
        }
        pos=m_positions.at(i);
        QPainterPath path;
        x=10+(re.width()-21)*pos->m_position/100;

        path.moveTo(x,0);
        path.lineTo(x-5,15);
        path.lineTo(x+5,15);
        path.lineTo(x,0);

        p.fillPath(path,QBrush(QColor(128,128,0)));

    }

    if(m_current_index>=0)
    {
        pos=m_positions.at(m_current_index);
        QPainterPath path;
        x=10+(re.width()-21)*pos->m_position/100;

        path.moveTo(x,0);
        path.lineTo(x-5,15);
        path.lineTo(x+5,15);
        path.lineTo(x,0);

        p.fillPath(path,QBrush(QColor(255,0,0)));
    }
}

QColorGroupDialog::QColorGroupDialog(const QVariant &value, QWidget *parent):
    QBaseDialog(parent),
    ui(new Ui::QColorGroupDialog),
    m_thermo(new QwtThermo),
    m_bar(new QColorPositionBar)
{
    ui->setupUi(this);

    m_colors=value.value<QGradient>();
    m_thermo->setScale(0,100);
    m_thermo->setScalePosition(QwtThermo::NoScale);
    m_thermo->setOrientation(Qt::Horizontal);
    m_thermo->setBorderWidth(0);
    m_thermo->setPipeWidth(15);
    m_thermo->setFixedHeight(15);
    m_thermo->setValue(100);
    m_thermo->setColorGroup(value.value<QGradient>());
    m_thermo->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Fixed);
    ui->horizontalLayout_4->insertWidget(0,m_thermo,1);
    ui->verticalLayout_2->insertWidget(1,m_bar);
    m_bar->add_position(m_colors.stops().at(0).first*100,
                        m_colors.stops().at(0).second);
    m_bar->add_position(m_colors.stops().last().first*100,
                        m_colors.stops().last().second);
    for(int i=1;i<m_colors.stops().size()-1;i++)
    {
        m_bar->add_position(m_colors.stops().at(i).first*100,
                            m_colors.stops().at(i).second);
    }

    if(m_colors.type()==QGradient::LinearGradient)
    {
        ui->comboBox->setCurrentIndex(0);
    }
    else
    {
        ui->comboBox->setCurrentIndex(1);
    }
    connect(m_bar,SIGNAL(current_changed()),this,SLOT(current_changed()));
    connect(m_bar,SIGNAL(refresh()),this,SLOT(pos_refresh()));

    m_bar->set_current(0);

    ui->label->installEventFilter(this);
}

QColorGroupDialog::~QColorGroupDialog()
{
    delete ui;
}

QVariant QColorGroupDialog::get_value()
{
    return m_value;
}

void QColorGroupDialog::on_comboBox_currentIndexChanged(int index)
{
    QGradient g;
    if(index==0)
    {
        g=QLinearGradient();
    }
    else
    {
        g=QRadialGradient();
    }
    g.setStops(m_colors.stops());
    m_colors=g;
    m_thermo->setColorGroup(g);
}

void QColorGroupDialog::pos_refresh()
{
    QList<tagColorPosition*> list=m_bar->get_positions();

    QGradient g;
    if(ui->comboBox->currentIndex()==0)
    {
        g=QLinearGradient();
    }
    else
    {
        g=QRadialGradient();
    }

    foreach(tagColorPosition *pos,list)
    {
        g.setColorAt(pos->m_position/100.0,pos->m_color);
    }

    m_colors=g;
    m_thermo->setColorGroup(g);
    m_bar->update();

    tagColorPosition *cur=m_bar->get_position(m_bar->get_current());
    ui->spinBox->setValue(cur->m_position);
}

void QColorGroupDialog::on_spinBox_valueChanged(int)
{
    m_bar->set_position(m_bar->get_current(),ui->spinBox->value());
}

void QColorGroupDialog::current_changed()
{
    int index=m_bar->get_current();

    ui->spinBox->setEnabled(index>1);
    tagColorPosition *pos=m_bar->get_position(index);
    ui->spinBox->setValue(pos->m_position);

    QPixmap pix(16,16);
    pix.fill(pos->m_color);
    ui->label->setPixmap(pix);

    ui->pushButton_3->setEnabled(index>1);
}

bool QColorGroupDialog::eventFilter(QObject *o, QEvent *e)
{
    if(o==ui->label && e->type()==QEvent::MouseButtonRelease)
    {
        tagColorPosition *p=m_bar->get_position(m_bar->get_current());
        QColor color=QColorDialog::getColor(p->m_color,this);
        if(color.isValid())
        {
            p->m_color=color;
            QPixmap pix(16,16);
            pix.fill(p->m_color);
            ui->label->setPixmap(pix);

            pos_refresh();
        }
    }
    return false;
}

void QColorGroupDialog::on_pushButton_4_clicked()
{
    m_bar->add_position(0,m_colors.stops().first().second);
    m_bar->set_current(m_bar->get_positions().size()-1);
    pos_refresh();
}

void QColorGroupDialog::on_pushButton_3_clicked()
{
    m_bar->remove_position(m_bar->get_current());
}

void QColorGroupDialog::on_pushButton_2_clicked()
{
    close();
}

void QColorGroupDialog::on_pushButton_clicked()
{
    m_value.setValue<QGradient>(m_colors);
    close();
}
